
// 枚举
/*
 * 枚举可以让你以不变应万变；
 */

// 数字枚举
let curClient = 'android';
enum osName {
  client = 1,
  browser,
  app,
  ios,
  android,
  weChat,
  wxMiniProgram,
  wxBrowser,
  alipay,
  streamApp
}
console.log(osName, Object.keys(osName).find((item: string) => item == curClient));
// {client: 0, browser: 1, 0: "client", 1: "browser", ...}

// 字符串枚举
enum osNameStr {
  client = "client1",
  browser = "browser1",
  app = "app1"
}
console.log(osNameStr, 'osNameStr');

// 异构枚举 不建议使用
enum tryOs {
  num,
  str = 'str'
}
console.log( tryOs, 'tryOs' );

// 枚举成员
/*
 * 枚举成员的值是只读类型；
 * 枚举成员分类：常量枚举：没有初始值、对已有枚举成员的引用、 常量的表达式；
 * 常量的枚举会在编译的时候执行出结果，在运行的时候作为常量执行
 * 在computed之后的枚举值一定要赋予初始值
 */
enum Char {
  a = 12
}
// Char.a = 34; // 枚举成员的值是只读类型
enum enumType {
  value1,
  value2 = Char.a,
  value3 = 1 + 3,

  // computed 需要被计算的枚举成员，这些不会在编译阶段执行计算，而是会被保留到程序的执行阶段；
  value4 = Math.random(),
  value5 = "123".length,
  
  value6 = 123, //必须赋予初始值
}
console.log(enumType, 'enumType');

// 常量枚举 
/*
 * 用 const声明, 特性：在编译阶段被移除，作用：当我们不要一个对象，但是需要对象值的时候; 
 * 好处，减少编译代码
 */
const enum Month {
  Jay,
  Fau,
  Mat,
}
// console.log(Month, "Month"); // 报错

let outputMonth: any = [Month.Jay, Month.Fau, Month.Mat];
console.log(outputMonth, "outputMonth");

// 枚举类型
/*
 * 在某种情况下，枚举和枚举成员都可以作为一种单独的类型存在；
 * 1、枚举成员没有初始值；
 * 2、所有成员都是数字枚举；
 * 3、所有成员都是字符串枚举；
 * 4、两种不同的枚举是不可以进行比较的；
 * 5、相同的枚举成员可以进行比较；
 */
enum type_one {x, y};
enum type_two {a = 0, b = 2};
enum type_three {d = "meiju01", e = "meiju02"};

let one: type_one = 0;
let two: type_two = 0;

// console.log(one == two);
let one3: type_one = 3;
let one4: type_one = 4;
console.log( one3 < one4 );

// 枚举成员类型
let twoA: type_two.a = 123;

// 字符串枚举的取值，必须是枚举成员的类型
let threeD: type_three = type_three.d;
let threeE: type_three = type_three.e;
let threeF: type_three.e = type_three.e; 